package org.dromara.common.wukong.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.RequiredArgsConstructor;
import okhttp3.Response;
import org.dromara.common.model.OkHttpUtils;
import org.dromara.common.wukong.constant.WuKongChannelConstant;
import org.dromara.common.wukong.dto.*;
import org.dromara.common.wukong.properties.WuKongImProperties;
import org.dromara.common.wukong.service.ChannelService;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 频道业务
 * @Author: Stars
 * @Date: 2025/3/10 21:12
 */
@RequiredArgsConstructor
public class ChannelServiceImpl implements ChannelService {

    private final WuKongImProperties wuKongImProperties;

    @Override
    public void createOrUpdateChannel(ChannelCreateOrUpdateDTO channelCreateOrUpdate) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL, channelCreateOrUpdate.convertToMap());
        if (response.code() != 200) {
            throw new IOException("创建或更新频道失败" + response.body().string());
        }
    }

    @Override
    public void delete(ChannelDeleteDTO channelDelete) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_DELETE, channelDelete.convertToMap());
        if (response.code() != 200) {
            throw new IOException("删除频道失败" + response.body().string());
        }
    }

    @Override
    public void addSubscribers(ChannelSubscriberAddDTO channelSubscriberAdd) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_SUBSCRIBER_ADD, channelSubscriberAdd.convertToMap());
        if (response.code() != 200) {
            throw new IOException("添加频道订阅者失败" + response.body().string());
        }
    }

    @Override
    public void removeSubscribers(ChannelSubscriberRemoveDTO channelSubscriberRemove) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_SUBSCRIBER_REMOVE, channelSubscriberRemove.convertToMap());
        if (response.code() != 200) {
            throw new IOException("移除频道订阅者失败" + response.body().string());
        }
    }

    @Override
    public void addToBlacklist(ChannelBlacklistAddDTO channelBlacklistAdd) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_BLACKLIST_ADD, channelBlacklistAdd.convertToMap());
        if (response.code() != 200) {
            throw new IOException("添加频道黑名单失败" + response.body().string());
        }
    }

    @Override
    public void removeFromBlacklist(ChannelBlacklistRemoveDTO channelBlacklistRemove) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_BLACKLIST_REMOVE, channelBlacklistRemove.convertToMap());
        if (response.code() != 200) {
            throw new IOException("移除频道黑名单失败" + response.body().string());
        }
    }

    @Override
    public void setBlacklist(ChannelBlacklistSetDTO channelBlacklistSet) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_BLACKLIST_SET, channelBlacklistSet.convertToMap());
        if (response.code() != 200) {
            throw new IOException("设置频道黑名单失败" + response.body().string());
        }
    }

    @Override
    public void addToWhitelist(ChannelWhitelistAddDTO channelWhitelistAdd) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_WHITELIST_ADD, channelWhitelistAdd.convertToMap());
        if (response.code() != 200) {
            throw new IOException("添加频道白名单失败" + response.body().string());
        }
    }

    @Override
    public void removeFromWhitelist(ChannelWhitelistRemoveDTO channelWhitelistRemove) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_WHITELIST_REMOVE, channelWhitelistRemove.convertToMap());
        if (response.code() != 200) {
            throw new IOException("移除频道白名单失败" + response.body().string());
        }
    }

    @Override
    public void setWhitelist(ChannelWhitelistSetDTO channelWhitelistSet) throws IOException {
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_WHITELIST_SET, channelWhitelistSet.convertToMap());
        if (response.code() != 200) {
            throw new IOException("设置频道白名单失败" + response.body().string());
        }
    }

    @Override
    public JSONArray syncOfflineMessage(String senderId, String receiverId, Long startMessageSeq, Long limit) throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("login_uid", senderId);
        map.put("channel_id", receiverId);
        map.put("channel_type", 1);
        // 这里 +1 是因为 当前这个序列号在APP本地已经存在了，所以我们要添加1 避开这条消息
        map.put("start_message_seq", startMessageSeq + 1);
        map.put("limit", limit);
        map.put("pull_mode", 1);

        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_MESSAGESYNC, map);
        if (response.code() == 200) {
            String body = response.body().string();
            JSONObject jsonObject = JSON.parseObject(body);
            JSONArray messagesArray = jsonObject.getJSONArray("messages");
            return messagesArray;
        }
        throw new IOException("查询用户离线消息失败" + response.body().string());
    }

    @Override
    public JSONArray syncOfflineGroupRecentlyMessage(String senderId, String receiverId,Long startMessageSeq, Long limit) throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("login_uid", senderId);
        map.put("channel_id", receiverId);
        map.put("channel_type", 2);
        map.put("start_message_seq", 0);
        map.put("end_message_seq", 0);
        map.put("limit", limit);
        map.put("pull_mode", 1);
        // 当 start_message_seq 和 end_message_seq 都为 0 时，查询最新的 limit条数据  。如果start_message_seq和end_message_seq都为0，则不管pull_mode为那种都加载最新的limit条消息。
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_MESSAGESYNC, map);
        if (response.code() == 200) {
            String body = response.body().string();
            JSONObject jsonObject = JSON.parseObject(body);
            return jsonObject.getJSONArray("messages");
        }
        throw new IOException("查询群离线消息失败" + response.body().string());
    }

    @Override
    public JSONArray syncGroupHistoryMessage(String senderId, String receiverId, Long startMessageSeq,Long endMessageSeq, Long limit) throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("login_uid", senderId);
        map.put("channel_id", receiverId);
        map.put("channel_type", 2);
        map.put("start_message_seq", startMessageSeq - 1);
        map.put("end_message_seq", endMessageSeq);
        map.put("limit", limit);
        map.put("pull_mode", 0);
        // 查询 小于或等于start_message_seq的消息 limit条 如果start_message_seq和end_message_seq都为0，则不管pull_mode为那种都加载最新的limit条消息。
        Response response = OkHttpUtils.post(wuKongImProperties.getUrl() + WuKongChannelConstant.CHANNEL_MESSAGESYNC, map);
        if (response.code() == 200) {
            String body = response.body().string();
            JSONObject jsonObject = JSON.parseObject(body);
            return jsonObject.getJSONArray("messages");
        }
        throw new IOException("查询群离线消息失败" + response.body().string());
    }
}
